package com.ninong.ker.common.exception.handler;

import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.ninong.ker.common.exception.CmdException;
import com.ninong.ker.common.exception.bean.CmdError;
import com.ninong.ker.common.response.CmdResponse;
import com.ninong.ker.common.tools.ThrowableUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 异常处理类
 * 
 * @author cmd
 * @date 2020年11月28日 下午11:22:48
 */

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

	/**
	 * 处理所有不可知的异常
	 */
	@ExceptionHandler(Throwable.class)
	public ResponseEntity<CmdError> handleException(Throwable e) {
		// 打印堆栈信息
		log.error(ThrowableUtil.getStackTrace(e));
		return buildResponseEntity(CmdError.error(e.getMessage()));
	}

	/**
	 * 处理自定义异常
	 */
	@ExceptionHandler(value = CmdException.class)
	public ResponseEntity<CmdResponse> badRequestException(CmdException e) {
		CmdResponse response = new CmdResponse();
		response.setCode(e.getStatus());
		response.setMessage(e.getMessage());
		return ResponseEntity.ok(response);
	}
	
	/**
     * 接口参数校验不通过异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity<CmdResponse> methodArgumentNotValidException(MethodArgumentNotValidException e) {
        List<FieldError> bindingResult = e.getBindingResult().getFieldErrors();
        StringBuilder sb = new StringBuilder();
        for (FieldError fieldError : bindingResult) {
            sb.append(fieldError.getDefaultMessage()).append(";");
        }
        CmdResponse response = new CmdResponse();
		response.setCode(100);
		response.setMessage(sb.toString());
        return ResponseEntity.ok(response);
    }


	/**
	 * 统一返回
	 */
	private ResponseEntity<CmdError> buildResponseEntity(CmdError cmdError) {
		return new ResponseEntity<>(cmdError, HttpStatus.valueOf(cmdError.getStatus()));
	}
}
